#include "OSScheduler.h"
#include <iostream>
#include "Network.h"
#include "ThreadTable.h"


OSScheduler::OSScheduler(Network* network) :
m_curThreadPhase(0),
m_curThread(NULL),
network(network) ,
totalContextSwitches(0) {
    tt = new ThreadTable(network->getNodeIds());
}

bool OSScheduler::checkThreadBlocked() {
    bool result = false;

    if (m_curThread != NULL) {
        // Check if the current thread's phase has changed from the last check
        int readThreadPhase = m_curThread->getPhase();

        // Check if the thread is still in the same phase
        if (m_curThreadPhase == readThreadPhase)
            result = true;

        m_curThreadPhase = readThreadPhase;

    }

    return result;
}

void OSScheduler::notifyThreadChange(Node* newThread) {
    if (m_curThread != NULL) {
        tt->setStatus(m_curThread->getId(), ThreadTable::BLOCKED);
    }

    m_curThread = newThread;

    // Save the thread's current phase
    m_curThreadPhase = m_curThread->getPhase();

    tt->setStatus(m_curThread->getId(), ThreadTable::RUNNING);

    totalContextSwitches++;
}

bool OSScheduler::currThreadStable() {
    bool blocked=tt->getUsedQuanta(m_curThread->getId())!=0;
    blocked = blocked && checkThreadBlocked();
    return blocked;
}

int OSScheduler::getTotalMsgQuantaGiven() {
    return tt->getTotalAccumulatedQuanta();
}

unsigned int OSScheduler::getTotalContextSwitches() {
    return totalContextSwitches;
}

string* OSScheduler::getThreadTableString() {
    return tt->getThreadTableString();
}

void OSScheduler::reset() {
    m_curThreadPhase=0;
    m_curThread=NULL;
    totalContextSwitches=0;
    tt = new ThreadTable(network->getNodeIds());
    childReset();
}
